/** * * Copyright 2013 Davide Nunes * Authors : Davide Nunes <davex.pt@gmail.com> * Website : http://davidenunes.com * * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER. * * This file is part of network-api. * * network-api is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * The network-api is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * You should have received a copy of the GNU General Public License * along with network-api. * If not, see <http://www.gnu.org/licenses/gpl.html>. */ package org.bhave.network.model.utils; import org.apache.commons.lang3.tuple.Pair; import org.apache.commons.math3.random.RandomGenerator; import org.apache.commons.math3.util.FastMath; public class NetworkModelUtils { /** * Considering all the possible links of an undirected network, we could * represent the links as an adjacency matrix (ignoring loops) such as: * * M = [ 01 02 03 04 ] [ 00 12 13 14 ] [ 00 00 23 24 ] [ 00 00 00 34 ] * * for a network with 5 nodes. * * This procedure transforms a linear index from a vector of possible edges: * * [ 01, 02, 03, 04, 12, 13, 14, 23, 24, 34 ] * * into the node IDS of the respective edge. * * For Instance, the index i=4 corresponds to the edge (1,2). The procedure * returns (1,2) without constructing a vector with all the links in the * network. * * @param index * the index of the link we want to retrieve 0 <= i < * Binomial(n,2) * @param numNodes * the number of nodes in the network * * @return a pair of IDS for the nodes in the link we want to retrieve. */ public static Pair<Integer, Integer> getLink(int index, int numNodes) { long maxI = numNodes - 1; long ii = (maxI * (maxI + 1) / 2) - 1 - index; double t = FastMath.sqrt(8 * ii + 1); long k = (long) FastMath.floor((t - 1) / 2); long row = maxI - 1 - k; double column = ((index + (row * (row + 1) / 2)) % maxI); int node1 = (int) row; int node2 = (int) (column + 1); return Pair.of(node1, node2); } /** * Utility used to select a random random (by id) excluding a given vector * of id values. This assumes that all the node IDs are sequential and a * network has at max a given number of nodes. * * @param random * a random number generator * @param numNodes * the max number of nodes * @param exclude * the IDs to be excluded from the selection * @return a random node id from the (numNodes) possible IDs. Assumes the * IDs are sequential and the exclude array is sorted by ascending * order */ public static int getRandomNode(RandomGenerator random, int numNodes, int[] exclude) { int r = random.nextInt(numNodes - exclude.length); for (int e : exclude) { if (r < e) { return r; } r++; } return r; } }